library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;

library work;
    use work.router_pack.all;
    use work.env_pack.all;
    
-------------------------------------------------------------------------
    
entity injector is
    
port(
    -- General Signals: --
    RESET           		: in std_logic;
    CLK             		: in std_logic;
    CYCLE_COUNTER   	: in std_logic_vector(e_cycle_counter_width_c-1 downto 0);
    MODULE_ID		: in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
    
    -- Output Port i/f: --
    RO      : out std_logic;
    AO      : in std_logic;
    DO      : out std_logic_vector(flit_size_c-1 downto 0);
    
    -- Environment Settings --
    WORKLOAD          : in std_logic_vector(e_workload_width_c-1 downto 0);
    MAX_VC            : in std_logic_vector(vc_width-1 downto 0);
    MAX_SL            : in std_logic_vector(msl_ind_width-1 downto 0);
    MAX_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    MIN_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    SEED1             : in std_logic_vector(e_seed_width_c-1 downto 0);
    SEED2             : in std_logic_vector(e_seed_width_c-1 downto 0)
);    
    
end injector;

-------------------------------------------------------------------------

architecture injector_arch of injector is

-- Injector Components --

component injector_if
port(
    -- General Signals: --
    RESET   	: in std_logic;
    CLK     	: in std_logic;
    
    -- Output Port i/f: --
    RO      : out std_logic;
    AO      : in std_logic;
    DO      : out std_logic_vector(flit_size_c-1 downto 0);
    
    -- Packet Info: --
    PACKET_REQ      	: in std_logic;
    SL              		: in std_logic_vector(msl_ind_width-1 downto 0);
    VC              		: in std_logic_vector(vc_width-1 downto 0);
    SOURCE_ROUTING  	: in std_logic_vector(e_flit_data_width_c-1 downto 0);
    PACKET_SIZE     	: in std_logic_vector(e_packet_size_width_c-1 downto 0);
    PACKET_ID       	: in std_logic_vector(e_packet_id_width_c-1 downto 0);
    PACKET_SENT     	: out std_logic;
    HEADER_SENT	     : out std_logic
);
end component;

component injector_packet_gen
port(
    -- General Signals: --
    RESET           		: in std_logic;
    CLK             		: in std_logic;
    MODULE_ID		: in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
    
    -- Packet Info: --
    PACKET_REQ      	: out std_logic;
    SL              		: out std_logic_vector(msl_ind_width-1 downto 0);
    VC              		: out std_logic_vector(vc_width-1 downto 0);
    SOURCE_ROUTING  	: out std_logic_vector(e_flit_data_width_c-1 downto 0);
    PACKET_SIZE     	: out std_logic_vector(e_packet_size_width_c-1 downto 0);
    PACKET_ID       	: out std_logic_vector(e_packet_id_width_c-1 downto 0);
    PACKET_SENT     	: in std_logic;
    
    -- Environment Settings --
    WORKLOAD          : in std_logic_vector(e_workload_width_c-1 downto 0);
    MAX_VC            : in std_logic_vector(vc_width-1 downto 0);
    MAX_SL            : in std_logic_vector(msl_ind_width-1 downto 0);
    MAX_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    MIN_PACKET_SIZE   : in std_logic_vector(e_packet_size_width_c-1 downto 0);
    SEED1             : in std_logic_vector(e_seed_width_c-1 downto 0);
    SEED2             : in std_logic_vector(e_seed_width_c-1 downto 0)
);
end component;

component loger
port(    
    -- General Signals: --
    RESET          		: in std_logic;
    CLK             		: in std_logic;
    CYCLE_COUNTER   	: in std_logic_vector(e_cycle_counter_width_c-1 downto 0);
    MODULE_ID		: in std_logic_vector(2*e_coord_position_width_c-1 downto 0);
    LOGER_TYPE		: in std_logic;
    
    -- Packet Info: --
    VALID           		: in std_logic;
    SL              		: in std_logic_vector(msl_ind_width-1 downto 0);
    PACKET_SIZE    	: in std_logic_vector(e_packet_size_width_c-1 downto 0);
    PACKET_ID      	: in std_logic_vector(e_packet_id_width_c-1 downto 0)
);
end component;

-- Internal Signals --
signal packet_req      	 : std_logic;
signal packet_sent      	: std_logic;
signal sl               	: std_logic_vector(msl_ind_width-1 downto 0);
signal vc               	: std_logic_vector(vc_width-1 downto 0);
signal source_routing   	: std_logic_vector(e_flit_data_width_c-1 downto 0);
signal packet_size      	: std_logic_vector(e_packet_size_width_c-1 downto 0);
signal packet_id        	: std_logic_vector(e_packet_id_width_c-1 downto 0);
signal loger_type			 : std_logic;
signal header_sent			 : std_logic;

-- Injector Implementation --

begin
    
    u_injector_if: injector_if
    port map(
       RESET            => RESET,
       CLK              => CLK,
    
       RO               => RO,
       AO               => AO,
       DO               => DO,
    
       PACKET_REQ       => packet_req,
       SL               => sl,
       VC               => vc,
       SOURCE_ROUTING   => source_routing,
       PACKET_SIZE      => packet_size,
       PACKET_ID        => packet_id,
       PACKET_SENT      => packet_sent,
       HEADER_SENT	     => header_sent
    );
    
    u_injector_packet_gen: injector_packet_gen
    port map(
       RESET            	=> RESET,
       CLK              	=> CLK,
       MODULE_ID 			 => MODULE_ID,
       
       PACKET_REQ       	=> packet_req,
       SL               	=> sl,
       VC               	=> vc,
       SOURCE_ROUTING    => source_routing,
       PACKET_SIZE      	=> packet_size,
       PACKET_ID        	=> packet_id,
       PACKET_SENT       => packet_sent,
       
       WORKLOAD         => WORKLOAD,
       MAX_VC           => MAX_VC,
       MAX_SL           => MAX_SL,
       MAX_PACKET_SIZE  => MAX_PACKET_SIZE,
       MIN_PACKET_SIZE  => MIN_PACKET_SIZE,
       SEED1			=> SEED1,
       SEED2			=> SEED2
    );
    
    u_loger: loger
    port map(
       RESET           	=> RESET,
       CLK             	=> CLK,
       CYCLE_COUNTER  	=> CYCLE_COUNTER,
       MODULE_ID 		=> MODULE_ID,
       LOGER_TYPE	=> loger_type,
       VALID           	=> header_sent,
       SL              	=> sl,
       PACKET_SIZE     	=> packet_size,
       PACKET_ID       	=> packet_id
    );
    
    -- Internal signals assignment
    loger_type <= loger_type_injector;
    
end injector_arch;
